package com.weipt.security;

import cn.hutool.core.util.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    private static final PasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        //校验用户名和密码
        Object principal = authentication.getPrincipal();
        Object credentials = authentication.getCredentials();
        if(ObjectUtil.isAllNotEmpty(principal, credentials)){
            String username = principal.toString();
            String password = credentials.toString();
            if(!username.equals(userDetails.getUsername())){
                throw new BadCredentialsException("用户名或密码错误");
            }
            if(!bCryptPasswordEncoder.matches(password, userDetails.getPassword())){
                throw new BadCredentialsException("用户名或密码错误");
            }
        }else{
            throw new BadCredentialsException("用户名或密码为空");
        }
    }


    //调用additionalAuthenticationChecks方法前，会先调用这个，获取用户对象，也就是用户后台真实的用户名和密码
    @Override
    protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        return userDetailsService.loadUserByUsername(username);
    }
}
